Skip to content

feat: enable sharing of chat sessions#1935

Open
onematchfox wants to merge 1 commit into
kagent-dev:mainfrom
onematchfox:share-chat
Open

feat: enable sharing of chat sessions#1935
onematchfox wants to merge 1 commit into
kagent-dev:mainfrom
onematchfox:share-chat

Conversation

@onematchfox
Copy link
Copy Markdown
Contributor

@onematchfox onematchfox commented May 27, 2026

Design choices are documented in #1933. Will address/respond to comments either here or there if needed and keep the implementation in sync as we go.

Closes #1933

@github-actions github-actions Bot added the enhancement New feature or request label May 27, 2026
Closes kagent-dev#1933

Signed-off-by: Brian Fox <878612+onematchfox@users.noreply.github.com>
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels May 27, 2026
@onematchfox onematchfox marked this pull request as ready for review May 27, 2026 16:49
Copilot AI review requested due to automatic review settings May 27, 2026 16:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds end-to-end “shared session” support via share tokens, including UI affordances to create/manage share links, frontend propagation of X-Share-Token, and backend persistence + enforcement (read-only vs read-write) for shared access.

Changes:

  • UI: create/manage share links, show shared-session indicators, and propagate share tokens through chat/task/A2A calls.
  • Backend (Go): add session share tables, middleware validation/enforcement, share CRUD endpoints, and session listing enhancements with share metadata.
  • Agent runtimes (Python/Go ADK) + Helm/CRDs: optional “share tools” injection and KAGENT_UI_URL plumbing for generating clickable share URLs.

Reviewed changes

Copilot reviewed 54 out of 59 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
ui/src/types/index.ts Extends Session type with optional share_token and share_read_only.
ui/src/lib/auth.ts Forwards x-share-token header by default.
ui/src/lib/a2aClient.ts Allows attaching X-Share-Token to streaming A2A requests; tightens types.
ui/src/lib/tests/auth.test.ts Updates default-forward-header expectations for share token forwarding.
ui/src/components/sidebars/SessionGroup.tsx Passes share metadata down to chat items.
ui/src/components/sidebars/ChatItem.tsx Appends ?share=... to shared-session links and shows shared icon.
ui/src/components/chat/ShareButton.tsx New client component to create/copy/revoke share links.
ui/src/components/chat/ChatMessage.tsx Simplifies ask-user submit callback wiring.
ui/src/components/chat/ChatInterface.tsx Propagates share token through reads/A2A and enforces read-only UI mode; adds ShareButton.
ui/src/components/chat/AskUserDisplay.tsx Disables ask-user interactions when handlers are absent (read-only mode).
ui/src/components/ToolDisplay.tsx Disables approve/reject buttons when no handlers (read-only mode).
ui/src/app/agents/[namespace]/[name]/chat/[chatId]/page.tsx Reads share query param and passes it to ChatInterface (with Suspense).
ui/src/app/actions/sessions.ts Adds optional shareToken header support for session/task fetches + getSessionWithEvents.
ui/src/app/actions/sessionShares.ts New server actions for session share CRUD.
python/packages/kagent-adk/tests/unittests/test_share_tools.py Adds unit tests for Python share tools.
python/packages/kagent-adk/src/kagent/adk/types.py Adds share_tools flag to AgentConfig and injects share tools when enabled.
python/packages/kagent-adk/src/kagent/adk/tools/share_tools.py Implements Python ADK share tools and URL generation.
python/packages/kagent-adk/src/kagent/adk/tools/init.py Exports the new Python share tools.
helm/kagent/values.yaml Adds controller.externalUrl for setting KAGENT_UI_URL.
helm/kagent/templates/controller-deployment.yaml Injects KAGENT_UI_URL into controller when configured.
helm/kagent-crds/templates/kagent.dev_sandboxagents.yaml Adds shareTools field to rendered CRD schema.
helm/kagent-crds/templates/kagent.dev_agents.yaml Adds shareTools field to rendered CRD schema.
go/core/pkg/migrations/core/000005_session_shares.up.sql Adds session_share and session_share_access tables.
go/core/pkg/migrations/core/000005_session_shares.down.sql Adds down migration (currently only drops one table).
go/core/pkg/env/kagent.go Registers KAGENT_UI_URL env var.
go/core/pkg/auth/share_test.go Unit tests for ShareContext helpers.
go/core/pkg/auth/share.go Adds ShareContext storage/retrieval in request context.
go/core/internal/httpserver/server_share_middleware_test.go Adds tests for share-token middleware behavior.
go/core/internal/httpserver/server.go Registers share routes and share-token middleware.
go/core/internal/httpserver/middleware.go Implements share-token validation, read-only enforcement, and access recording.
go/core/internal/httpserver/handlers/sessions_test.go Extends session handler tests for read_only field + updated list type.
go/core/internal/httpserver/handlers/sessions_share_context_test.go Adds tests for effective user ID resolution under share context.
go/core/internal/httpserver/handlers/sessions.go Uses ShareContext for DB lookups + returns read_only in responses.
go/core/internal/httpserver/handlers/session_shares_test.go Adds tests for session share CRUD handlers.
go/core/internal/httpserver/handlers/session_shares.go Implements session share CRUD endpoints.
go/core/internal/httpserver/handlers/handlers.go Wires SessionSharesHandler into handler set.
go/core/internal/httpserver/auth/authn.go Forces agent upstream calls to use share owner’s X-User-Id when share context present.
go/core/internal/database/queries/sessions.sql Enhances session listing to include shared sessions and share metadata.
go/core/internal/database/queries/session_shares.sql Adds SQL queries for share CRUD and access upsert.
go/core/internal/database/client_postgres.go Implements DB methods for shares + new session list return type.
go/core/internal/controller/translator/agent/manifest_builder.go Propagates KAGENT_UI_URL into agent pods when set.
go/core/internal/controller/translator/agent/compiler.go Passes shareTools flag into ADK AgentConfig.
go/core/internal/a2a/manager_test.go Tests initiated_by injection when share context is present.
go/core/internal/a2a/manager.go Injects initiated_by metadata for shared-session A2A messages.
go/api/v1alpha2/agent_types.go Adds shareTools field to Agent CRD Go types.
go/api/database/models.go Adds SessionWithShareToken and SessionShare models.
go/api/database/client.go Extends DB client interface with share methods and updated session list signature.
go/api/config/crd/bases/kagent.dev_sandboxagents.yaml Adds shareTools to generated CRD base.
go/api/config/crd/bases/kagent.dev_agents.yaml Adds shareTools to generated CRD base.
go/api/adk/types.go Adds share_tools to ADK AgentConfig JSON handling.
go/adk/pkg/tools/share_tools_test.go Adds tests for Go ADK share tools.
go/adk/pkg/tools/share_tools.go Implements Go ADK share tools and URL generation.
go/adk/pkg/runner/adapter.go Conditionally injects share tools into Go ADK runner.
go/adk/cmd/main.go Passes HTTP client + kagent URL into runner config for share tools.
Files not reviewed (5)
  • go/api/v1alpha2/zz_generated.deepcopy.go: Language not supported
  • go/core/internal/database/gen/models.go: Language not supported
  • go/core/internal/database/gen/querier.go: Language not supported
  • go/core/internal/database/gen/session_shares.sql.go: Language not supported
  • go/core/internal/database/gen/sessions.sql.go: Language not supported
Comments suppressed due to low confidence (8)

go/core/pkg/migrations/core/000005_session_shares.down.sql:1

  • The down migration drops session_share but not session_share_access. Since session_share_access has a foreign key referencing session_share, dropping session_share first will fail in Postgres (or leave orphaned objects depending on settings). Drop session_share_access first, then session_share (and consider dropping the index too for completeness).
    ui/src/components/chat/ShareButton.tsx:1
  • This references window during render. In Next.js App Router, client components can still be pre-rendered on the server, where window is undefined, causing a runtime crash. Compute origin inside an effect (store in state), or guard with typeof window !== \"undefined\" before reading window.location.origin.
    ui/src/components/chat/ChatInterface.tsx:1
  • shareReadOnly is only set inside the shareToken branch. If the user navigates from a shared read-only session to a non-shared session without a full remount, shareReadOnly can remain true and incorrectly disable interactions. Reset shareReadOnly to false when shareToken is absent (e.g., at the start of initialization or in the else branch).
    ui/src/components/chat/ChatInterface.tsx:1
  • shareReadOnly is only set inside the shareToken branch. If the user navigates from a shared read-only session to a non-shared session without a full remount, shareReadOnly can remain true and incorrectly disable interactions. Reset shareReadOnly to false when shareToken is absent (e.g., at the start of initialization or in the else branch).
    ui/src/components/chat/ChatInterface.tsx:1
  • shareReadOnly is only set inside the shareToken branch. If the user navigates from a shared read-only session to a non-shared session without a full remount, shareReadOnly can remain true and incorrectly disable interactions. Reset shareReadOnly to false when shareToken is absent (e.g., at the start of initialization or in the else branch).
    ui/src/components/sidebars/ChatItem.tsx:1
  • The share token is inserted into the URL query string without encoding and will be stored in browser history and may leak via referrer headers/logs. At minimum, wrap the token with encodeURIComponent (or build via URLSearchParams) to prevent malformed URLs; consider using a URL fragment (e.g. #share=...) if feasible so the token is not emitted as an HTTP referrer, while still being readable by the client.
    python/packages/kagent-adk/src/kagent/adk/tools/share_tools.py:1
  • Docstring says that without KAGENT_UI_URL the function returns only the raw token, but the implementation returns a relative path containing ?share=<token>. Update the docstring to match actual behavior (relative path vs raw token).
    ui/src/components/chat/ShareButton.tsx:1
  • This input has no accessible name (no associated <Label> and no aria-label), which makes the share URL harder to discover for screen reader users. Add an aria-label (e.g. "Share link") or associate it with a visible label.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +147 to +156
userID, err := GetUserID(r)
if err != nil {
w.RespondWithError(errors.NewBadRequestError("failed to get user ID", err))
return
}

if err := h.DatabaseService.DeleteSessionShare(r.Context(), token, sessionID, userID); err != nil {
w.RespondWithError(errors.NewInternalServerError("failed to delete share", err))
return
}
Comment on lines +14 to +25
ELSE (SELECT ss.token FROM session_share ss
JOIN session_share_access sa ON sa.share_id = ss.id
WHERE ss.session_id = s.id AND sa.user_id = $2
ORDER BY ss.read_only ASC, ss.created_at DESC LIMIT 1)
END) AS share_token,
(CASE WHEN s.user_id = $2 THEN NULL::boolean
ELSE (SELECT ss.read_only FROM session_share ss
JOIN session_share_access sa ON sa.share_id = ss.id
WHERE ss.session_id = s.id AND sa.user_id = $2
ORDER BY ss.read_only ASC, ss.created_at DESC LIMIT 1)
END) AS share_read_only
FROM session s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Session sharing

2 participants